package cn.hrc.service.impl;

import cn.hrc.dao.BookMapper;
import cn.hrc.entity.Book;
import cn.hrc.service.BookService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class BookServiceImpl implements BookService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    BookMapper bookMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Override /** 查询全部 Book (商品) */
    public List<Book> findAll() {
        logger.info("Redis 查询全部商品");
        // 从缓存中获取 Book 全部数据
        List<Book> books = redisTemplate.opsForHash().values("hrc:book");
        // 如果缓存中有数据 直接 返回
        if(books != null)return books;
        // 如果缓存中没有数据 从数据库中获取
        logger.info("SQL 查询全部商品");
        books = bookMapper.selectByMap(null);
        // 将数据放入缓存中
        logger.info("Redis 添加全部商品");
        for (Book book : books){
            redisTemplate.opsForHash()
                    .put("hrc:book",book.getId(),book);
        }
        // 返回数据
        return books;
    }
    @Override
    public Book findById(int id) {
        logger.info("Redis 查询商品");
        Book book = (Book)redisTemplate.opsForHash().get("hrc:book", id);
        // 如果缓存中有数据 直接 返回
        if (book != null) return book;
        logger.info("SQL 查询商品");
        book = bookMapper.selectById(id);
        logger.info("Redis 添加商品");
        redisTemplate.opsForHash()
                .put("hrc:book",book.getId(),book);
        // 返回数据
        return book;
    }

    @Override
    public List<Book> findByPage(Integer page, Integer size, Integer type,String name) {
            logger.info("SQL 分页查询");
            QueryWrapper wrapper = new QueryWrapper<Book>()
                    // like name '%"+name+"%'
                    .like("name",name)
                    // eq typeid = type
                    .eq("typeid",type)
                    // limit page,size
                    .last("limit "+page+","+size);
        List<Book> list = bookMapper.selectList(wrapper);

        return list;
    }

    @Override // 添加图书
    /** @Transactional  */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public int addBook(Book book) {
        logger.info("SQL 添加图书");
        int n = bookMapper.insert(book);
        if (n == 0) return n;
        logger.info("Redis 添加图书");
        redisTemplate.opsForHash() // 添加到缓存中
                .put("hrc:book",book.getId(),book);
        redisTemplate.opsForZSet() // 添加到排行榜中
                .add("book",book,book.getSalenum());
        logger.info("添加成功图书");
        return n;
    }

    @Override // 删除图书
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public int deleteBook(int id) {
        logger.info("SQL 删除图书");
        int n = 0;
        try {
            n = bookMapper.deleteById(id);
            if (n == 0) return n;
            logger.info("Redis 删除图书：双删");

        } catch (Exception e) {
            System.out.println("删除图书失败");
        }
        return n;
    }

    @Override // 更新图书
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public int updateBook(Book book) {
        logger.info("Redis 更新图书：双删");
        int n = 0;
        try {
            redisTemplate.opsForHash()
                    .delete("hrc:book",book.getId());
            logger.info("SQL 更新图书");
            n = bookMapper.updateById(book);
            if (n == 0) return n;
            Thread.sleep(100);
            logger.info("Redis 添加图书");
            redisTemplate.opsForHash()
                    .put("hrc:book",book.getId(),book);
        } catch (InterruptedException e) {
            System.out.println("修改图书失败");
        }
        return n;
    }
}
